const cloudHelper = require('../../../helpers/cloud_helper.js');
const pageHelper = require('../../../helpers/page_helper.js');

Component({
  /**
   * 组件的属性列表
   */
  properties: {
    projectId: {
      type: String,
      value: ''
    },
    showBranch: {
      type: Boolean,
      value: true
    },
    showFlow: {
      type: Boolean,
      value: true
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    isLoad: false,
    
    // 图谱数据
    graphData: null,
    
    // 图谱渲染配置
    canvasWidth: 0,
    canvasHeight: 0,
    
    // 节点配置
    nodeRadius: 20,
    nodeColors: {
      project: '#0066cc',
      branch: '#52c41a',
      flow: '#faad14'
    },
    
    // 连线配置
    lineColors: {
      branch: '#52c41a',
      flow: '#faad14'
    },
    
    // 交互状态
    isDragging: false,
    lastX: 0,
    lastY: 0,
    offsetX: 0,
    offsetY: 0,
    scale: 1
  },

  /**
   * 组件的生命周期
   */
  lifetimes: {
    attached() {
      this._initCanvas();
      this._loadGraphData();
    },
    
    detached() {
      // 清理资源
    }
  },

  /**
   * 属性变化监听
   */
  observers: {
    'showBranch, showFlow': function(showBranch, showFlow) {
      // 当显示选项变化时，重新加载数据
      this._loadGraphData();
    }
  },

  /**
   * 组件的方法列表
   */
  methods: {
    /**
     * 初始化画布
     */
    _initCanvas() {
      const query = this.createSelectorQuery();
      query.select('#graph-canvas')
        .fields({ node: true, size: true })
        .exec((res) => {
          if (!res || !res[0]) return;
          
          const canvas = res[0].node;
          const ctx = canvas.getContext('2d');
          
          // 使用推荐的API获取设备像素比
          let dpr = 1;
          try {
            const deviceInfo = wx.getDeviceInfo();
            dpr = deviceInfo.pixelRatio || 1;
          } catch (error) {
            console.warn('获取设备像素比失败，使用默认值', error);
          }
          
          canvas.width = res[0].width * dpr;
          canvas.height = res[0].height * dpr;
          ctx.scale(dpr, dpr);
          
          this.canvas = canvas;
          this.ctx = ctx;
          
          this.setData({
            canvasWidth: res[0].width,
            canvasHeight: res[0].height
          });
          
          // 如果数据已加载，则渲染图谱
          if (this.data.graphData) {
            this._renderGraph();
          }
        });
    },
    
    /**
     * 加载图谱数据
     */
    async _loadGraphData() {
      if (!this.properties.projectId) {
        console.error('项目ID不能为空');
        return;
      }
      
      try {
        wx.showLoading({
          title: '加载中...',
        });
        
        const params = {
          id: this.properties.projectId,
          showBranch: this.properties.showBranch,
          showFlow: this.properties.showFlow
        };
        
        const result = await cloudHelper.callCloudData('research/graph', params);
        
        this.setData({
          isLoad: true,
          graphData: result
        });
        
        wx.hideLoading();
        
        // 如果画布已初始化，则渲染图谱
        if (this.ctx) {
          this._renderGraph();
        }
      } catch (err) {
        console.error('加载图谱数据失败', err);
        
        wx.hideLoading();
        
        pageHelper.showModal('加载失败，请重试');
      }
    },
    
    /**
     * 渲染图谱
     */
    _renderGraph() {
      if (!this.ctx || !this.data.graphData) return;
      
      const { nodes, links } = this.data.graphData;
      const { canvasWidth, canvasHeight, nodeRadius, scale, offsetX, offsetY } = this.data;
      
      // 清空画布
      this.ctx.clearRect(0, 0, canvasWidth, canvasHeight);
      
      // 应用缩放和平移
      this.ctx.save();
      this.ctx.translate(offsetX, offsetY);
      this.ctx.scale(scale, scale);
      
      // 绘制连线
      this._drawLinks(links);
      
      // 绘制节点
      this._drawNodes(nodes);
      
      this.ctx.restore();
    },
    
    /**
     * 绘制节点
     * @param {Array} nodes 节点数据
     */
    _drawNodes(nodes) {
      if (!nodes || !nodes.length) return;
      
      const { nodeRadius, nodeColors } = this.data;
      
      nodes.forEach(node => {
        const { x, y, type, label } = node;
        
        // 绘制节点圆形
        this.ctx.beginPath();
        this.ctx.arc(x, y, nodeRadius, 0, Math.PI * 2);
        this.ctx.fillStyle = nodeColors[type] || nodeColors.project;
        this.ctx.fill();
        
        // 绘制节点标签
        this.ctx.font = '12px Arial';
        this.ctx.fillStyle = '#333';
        this.ctx.textAlign = 'center';
        this.ctx.textBaseline = 'middle';
        this.ctx.fillText(label, x, y + nodeRadius + 15);
      });
    },
    
    /**
     * 绘制连线
     * @param {Array} links 连线数据
     */
    _drawLinks(links) {
      if (!links || !links.length) return;
      
      const { lineColors } = this.data;
      
      links.forEach(link => {
        const { source, target, type } = link;
        
        this.ctx.beginPath();
        this.ctx.moveTo(source.x, source.y);
        this.ctx.lineTo(target.x, target.y);
        this.ctx.strokeStyle = lineColors[type] || '#999';
        this.ctx.lineWidth = 2;
        this.ctx.stroke();
        
        // 绘制箭头
        this._drawArrow(source.x, source.y, target.x, target.y, lineColors[type] || '#999');
      });
    },
    
    /**
     * 绘制箭头
     * @param {Number} fromX 起点X
     * @param {Number} fromY 起点Y
     * @param {Number} toX 终点X
     * @param {Number} toY 终点Y
     * @param {String} color 颜色
     */
    _drawArrow(fromX, fromY, toX, toY, color) {
      const { nodeRadius } = this.data;
      
      // 计算方向向量
      const dx = toX - fromX;
      const dy = toY - fromY;
      const len = Math.sqrt(dx * dx + dy * dy);
      
      // 计算箭头位置（距离终点节点边缘）
      const endX = toX - (dx / len) * nodeRadius;
      const endY = toY - (dy / len) * nodeRadius;
      
      // 计算箭头角度
      const angle = Math.atan2(dy, dx);
      const arrowSize = 8;
      
      // 绘制箭头
      this.ctx.beginPath();
      this.ctx.moveTo(endX, endY);
      this.ctx.lineTo(
        endX - arrowSize * Math.cos(angle - Math.PI / 6),
        endY - arrowSize * Math.sin(angle - Math.PI / 6)
      );
      this.ctx.lineTo(
        endX - arrowSize * Math.cos(angle + Math.PI / 6),
        endY - arrowSize * Math.sin(angle + Math.PI / 6)
      );
      this.ctx.closePath();
      this.ctx.fillStyle = color;
      this.ctx.fill();
    },
    
    /**
     * 触摸开始事件
     * @param {Object} e 事件对象
     */
    onTouchStart(e) {
      const touch = e.touches[0];
      this.setData({
        isDragging: true,
        lastX: touch.x,
        lastY: touch.y
      });
    },
    
    /**
     * 触摸移动事件
     * @param {Object} e 事件对象
     */
    onTouchMove(e) {
      if (!this.data.isDragging) return;
      
      const touch = e.touches[0];
      const { lastX, lastY, offsetX, offsetY } = this.data;
      
      const dx = touch.x - lastX;
      const dy = touch.y - lastY;
      
      this.setData({
        lastX: touch.x,
        lastY: touch.y,
        offsetX: offsetX + dx,
        offsetY: offsetY + dy
      });
      
      this._renderGraph();
    },
    
    /**
     * 触摸结束事件
     */
    onTouchEnd() {
      this.setData({
        isDragging: false
      });
    },
    
    /**
     * 缩放事件
     * @param {Object} e 事件对象
     */
    onScale(e) {
      const { scale } = e.detail;
      
      this.setData({
        scale: scale > 0.5 ? (scale < 2 ? scale : 2) : 0.5
      });
      
      this._renderGraph();
    },
    
    /**
     * 重置视图
     */
    resetView() {
      this.setData({
        offsetX: 0,
        offsetY: 0,
        scale: 1
      });
      
      this._renderGraph();
    }
  }
}); 